package org.example.bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpSocketServer extends Thread {

  private static final Logger logger = LoggerFactory.getLogger(HttpSocketServer.class);

  private final ServerSocket serverSocket;
  private final Executor executor;

  public HttpSocketServer(int port) throws IOException {
    serverSocket = new ServerSocket(port);
    executor = new ThreadPoolExecutor(2, 100, 100, TimeUnit.SECONDS,
        new LinkedBlockingDeque<>(120), new ThreadPoolExecutor.DiscardPolicy());
  }

  @Override
  public void run() {
    while (true) {
      try {
        logger.info("Waiting for client on port {} ... ", serverSocket.getLocalPort());
        Socket requestSocket = serverSocket.accept();
        executor.execute(() -> {
          logger.info("Just connected to {}", requestSocket.getRemoteSocketAddress());
          new HttpHandler(requestSocket).handler();
        });
      }
      catch (SocketTimeoutException s) {
        logger.error("Socket timed out!");
        break;
      }
      catch (IOException e) {
        logger.error("Socket error", e);
        break;
      }
    }
  }
}
